#! /bin/bash

set -e
function info { echo -e "\e[32m[info] $*\e[39m"; }
function warn { echo -e "\e[33m[warn] $*\e[39m"; }
function error { echo -e "\e[31m[error] $*\e[39m"; }

if [ ! -f configmap.yaml ];then
    echo "Run the following command to create the 'configmap.yaml' file."
    echo '  cp configmap.yaml.example configmap.yaml'
    exit 0
fi

# Code related
ALGORITHM_REPO=$(cat configmap.yaml | grep "^  algorithm.repo:" | cut -d"\"" -f2 | tr -d ' ')
GIT_REPO=$(cat configmap.yaml | grep "^  code.repo:" | cut -d"\"" -f2 | tr -d ' ')
GIT_BRANCH=$(cat configmap.yaml | grep "^  code.branch:" | cut -d"\"" -f2 | tr -d ' ')
# Environment config
DUBHE_ENVIRONMENT=$(cat configmap.yaml | grep "^  dubhe.environment:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
# Nacos config
NACOS_SERVER=$(cat configmap.yaml | grep "^  nacos.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
NACOS_PORT=$(cat configmap.yaml | grep "^  nacos.port:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
NACOS_USER=$(cat configmap.yaml | grep "^  nacos.mysql.user:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
NACOS_PASSWORD=$(cat configmap.yaml | grep "^  nacos.mysql.password:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
# Minio config
MINIO_SERVER=$(cat configmap.yaml | grep "^  minio.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
MINIO_PORT=$(cat configmap.yaml | grep "^  minio.port:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
# Backend config
BACKEND_SERVER=$(cat configmap.yaml | grep "^  backend.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
BACKEND_K8S_SERVER=$(cat configmap.yaml | grep "^  backend.k8s.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
BACKEND_GATEWAY_SERVER=$(cat configmap.yaml | grep "^  backend.gateway.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
BACKEND_DCM4CHEE_SERVER=$(cat configmap.yaml | grep "^  backend.dcm4chee.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
WEB_PROXY_HOST=$(cat configmap.yaml | grep "^  web.proxy.host:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
NGINX_PROXY_MINIO=$(cat configmap.yaml | grep "^  elasticsearch.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
# Redis definition
REDIS_PASSWORD=$(cat configmap.yaml | grep "^  redis.password:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
REDIS_SERVER=$(cat configmap.yaml | grep "^  redis.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
# Web
WEB_SERVER=$(cat configmap.yaml | grep "^  web.server:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')

# Image config
# Mysql
MYSQL_IMAGE=$(cat configmap.yaml | grep "^  image.mysql:" | cut -d"\"" -f2)
MYSQL_INIT_IMAGE=$(cat configmap.yaml | grep "^  image.mysql-init:" | cut -d"\"" -f2)
# Minio
MINIO_IMAGE=$(cat configmap.yaml | grep "^  image.minio:" | cut -d"\"" -f2)
MINIO_INIT_IMAGE=$(cat configmap.yaml | grep "^  image.minio-init:" | cut -d"\"" -f2)
# Nacos
NACOS_IMAGE=$(cat configmap.yaml | grep "^  image.nacos:" | cut -d"\"" -f2)
NACOS_INIT_IMAGE=$(cat configmap.yaml | grep "^  image.nacos-init:" | cut -d"\"" -f2)
# Redis
REDIS_IMAGE=$(cat configmap.yaml | grep "^  image.redis" | cut -d"\"" -f2)
# Storage init
STORAGE_INIT_IMAGE=$(cat configmap.yaml | grep "^  image.storage-init:" | cut -d"\"" -f2)
# ES init
ES_INIT_IMAGE=$(cat configmap.yaml | grep "^  image.elasticsearch-init:" | cut -d"\"" -f2)

# Backend
BACKEND_IMAGE=$(cat configmap.yaml | grep "^  image.backend:" | cut -d"\"" -f2)
BACKEND_INIT_IMAGE=$(cat configmap.yaml | grep "^  image.backend-init:" | cut -d"\"" -f2)
BACKEND_VISUAL_IMAGE=$(cat configmap.yaml | grep "^  image.backend-visual:" | cut -d"\"" -f2)
BACKEND_NGINX=$(cat configmap.yaml | grep "^  image.nginx:" | cut -d"\"" -f2)

#Web
WEB_IMAGE=$(cat configmap.yaml | grep "^  image.web:" | cut -d"\"" -f2)
#Alogirithm image
ALGORITHM_IMGPROCESS_IMAGE=$(cat configmap.yaml | grep "^  image.imgprocess.algorithm:" | cut -d"\"" -f2)
ALGORITHM_OFRECORD_IMAGE=$(cat configmap.yaml | grep "^  image.ofrecord.algorithm:" | cut -d"\"" -f2)
ALGORITHM_VIDEOSAMPLE_IMAGE=$(cat configmap.yaml | grep "^  image.videosample.algorithm:" | cut -d"\"" -f2)
#MODEL
## MODEL_CONVERTER_IMAGE
MODEL_CONVERTER_IMAGE=$(cat configmap.yaml | grep "^  image.converter:" | cut -d"\"" -f2)
## MODEL_MEASURING_IMAGE
MODEL_MEASURING_IMAGE=$(cat configmap.yaml | grep "^  image.measuring:" | cut -d"\"" -f2)

# Storage config
STORAGE_CLASS=$(cat configmap.yaml | grep "^  storage.classname:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
STORAGE_SIZE=$(cat configmap.yaml | grep "^  storage.size:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')
STORAGE_PATH=$(cat configmap.yaml | grep "^  storage.path:" | cut -d":" -f2 | tr -d ' ' | tr -d '"')


INFRA_IMAGE=$(cat configmap.yaml | grep "^  image.infra:" | cut -d"\"" -f2)
KIBANA_IMAGE=$(cat configmap.yaml | grep "^  image.kibana:" | cut -d"\"" -f2)
ELASTICSEARCH_IMAGE=$(cat configmap.yaml | grep "^  image.elasticsearch:" | cut -d"\"" -f2)
FLUENT_IMAGE=$(cat configmap.yaml | grep "^  image.fluent:" | cut -d"\"" -f2)
NODEXPORTER_IMAGE=$(cat configmap.yaml | grep "^  image.nodexporter:" | cut -d"\"" -f2)
PROMETHEUS_IMAGE=$(cat configmap.yaml | grep "^  image.prometheus:" | cut -d"\"" -f2)
GRAFANA_IMAGE=$(cat configmap.yaml | grep "^  image.grafana:" | cut -d"\"" -f2)

DCM4CHEE_LDAP_IMAGE=$(cat configmap.yaml | grep "^  image.dcm4chee.ldap:" | cut -d"\"" -f2)
DCM4CHEE_LDAP_POSTGRES_IMAGE=$(cat configmap.yaml | grep "^  image.dcm4chee.postgres:" | cut -d"\"" -f2)
DCM4CHEE_LDAP_ARC_IMAGE=$(cat configmap.yaml | grep "^  image.dcm4chee.arc:" | cut -d"\"" -f2)


ROOTDIR=$(pwd)

# Build image for backend.
# Backend service such as admin is based on this image.
funcBuildImageBackend() {
    cd $ROOTDIR

    log "Start to build backend image...\n"

    cp template/bootstrap.yml image/backend/bootstrap-prod.yml
    cp template/kubeconfig.yaml image/backend/kubeconfig-prod

    sed -i "s/DUBHE_ENVIRONMENT/$DUBHE_ENVIRONMENT/g" image/backend/bootstrap-prod.yml
    sed -i "s/NACOS_SERVER/$NACOS_SERVER/g" image/backend/bootstrap-prod.yml
    sed -i "s/NACOS_PORT/$NACOS_PORT/g" image/backend/bootstrap-prod.yml
    sed -i "s/NACOS_USER/$NACOS_USER/g" image/backend/bootstrap-prod.yml
    sed -i "s/NACOS_PASSWORD/$NACOS_PASSWORD/g" image/backend/bootstrap-prod.yml

    # Copy Dubhe code.
    if [ ! -d "image/backend/Dubhe" ]; then
        cp -r Dubhe image/backend/
    fi

    # In backend image directory
    cd image/backend

    cp kubeconfig-prod Dubhe/dubhe-server/common-k8s/src/main/resources/kubeconfig
    cp bootstrap-prod.yml Dubhe/dubhe-server/common-cloud/configuration/src/main/resources/

    # Compile backend with maven
    docker run --rm --entrypoint="" -v $PWD/Dubhe:/Dubhe maven:3.5-jdk-8 /bin/bash -c 'cd /Dubhe/dubhe-server/ && mvn clean compile package'

    cd Dubhe/dubhe-server

    docker build -t $BACKEND_IMAGE ./
    docker push $BACKEND_IMAGE
    cd $ROOTDIR

    log "Please push image $BACKEND_IMAGE to image repo if needed\n"
}

# Build image for web.
funcBuildImageWeb() {
    cd $ROOTDIR

    log "Start to build web image...\n"
    # Just use production environment
    cp template/env.production image/web/env.production
    cp template/nginx.conf image/web/nginx.conf
    cp template/default.conf image/web/default.conf
    # Web service will visit minio and backend-k8s.
    # if [[ $WEB_PROXY_HOST =~ ^([a-zA-Z0-9](-?[a-zA-Z0-9])*\.)+[a-zA-Z]{2,}$ ]]; then
    if [ -z $WEB_PROXY_HOST ]; then
        # Visit by domain
        sed -i "s/DUBHE_ENVIRONMENT/$DUBHE_ENVIRONMENT/g" image/web/env.production
        sed -i "s/DUBHE_BACKEND_SERVER/$BACKEND_K8S_SERVER/g" image/web/env.production
        sed -i "s/DUBHE_MINIO_SERVER/$MINIO_SERVER/g" image/web/env.production
        sed -i "s/DUBHE_MINIO_PORT/$MINIO_PORT/g" image/web/env.production
        sed -i "s/DUBHE_MINIO_SERVER/$MINIO_SERVER/g" image/web/default.conf
        sed -i "s/DUBHE_MINIO_PORT/$MINIO_PORT/g" image/web/default.conf
        sed -i "s/DUBHE_WEB_SERVER/$WEB_SERVER/g" image/web/default.conf
        sed -i "s/DUBHE_BACKEND_GATEWAY_SERVER/$BACKEND_GATEWAY_SERVER/g" image/web/default.conf
        sed -i "s/DUBHE_BACKEND_DCM4CHEE_SERVER/$BACKEND_DCM4CHEE_SERVER/g" image/web/default.conf
        sed -i "s/DUBHE_BACKEND_DCM4CHEE_SERVER/$BACKEND_DCM4CHEE_SERVER/g" image/web/env.production
    else
        # Visit by node proxy
        sed -i "s/DUBHE_ENVIRONMENT/$DUBHE_ENVIRONMENT/g" image/web/env.production
        sed -i "s/DUBHE_BACKEND_SERVER/$WEB_PROXY_HOST/g" image/web/env.production
        sed -i "s/DUBHE_MINIO_SERVER/$WEB_PROXY_HOST/g" image/web/env.production
        sed -i "s/DUBHE_BACKEND_DCM4CHEE_SERVER:8080/$NGINX_PROXY_MINIO:30088/g" image/web/default.conf
        sed -i "s/DUBHE_WEB_SERVER/$WEB_PROXY_HOST:30800/g" image/web/env.production
        sed -i "s/DUBHE_MINIO_PORT/30900/g" image/web/env.production
        sed -i "s/8960/30960/g" image/web/env.production
        sed -i "s/DUBHE_MINIO_SERVER/$NGINX_PROXY_MINIO/g" image/web/default.conf
        sed -i "s/DUBHE_MINIO_PORT/9000/g" image/web/default.conf
        sed -i "s/DUBHE_BACKEND_GATEWAY_SERVER/$BACKEND_GATEWAY_SERVER/g" image/web/default.conf
    fi

    # Copy Dubhe code.
    if [ ! -d "image/web/Dubhe" ]; then
        cp -r Dubhe image/web/
    fi

    # In web image directory
    cd image/web

    cp env.production Dubhe/webapp/.env.production

    # Compile web image
    docker run --rm --net host --entrypoint="" -v $PWD/Dubhe:/Dubhe node:12.22.4 /bin/bash -c 'cd /Dubhe/webapp/ && npm config set registry https://registry.npmmirror.com && npm install && npm run build:prod'

    docker build -t $WEB_IMAGE ./
    docker push $WEB_IMAGE

    cd $ROOTDIR

    log "Please push image $WEB_IMAGE to image repo if needed\n"
}

# Build image for minio initializing.
funcBuildImageMinioInit() {
    cd $ROOTDIR

    log "Start to build minio-init image...\n"

    # In web image directory
    cd image/minio-ini

    docker build -t $MINIO_INIT_IMAGE ./
    docker push $MINIO_INIT_IMAGE
    cd $ROOTDIR

    log "Please push image $MINIO_INIT_IMAGE to image repo if needed\n"
}

# Build image for Model-Converter
funcBuildImageModel-Converter() {
    cd $ROOTDIR

    log "Start to build model-converter image...\n"

    # In model-converter directory
    cd image/model-converter
    docker build -t $MODEL_CONVERTER_IMAGE ./
    docker push $MODEL_CONVERTER_IMAGE
    cd $ROOTDIR

    log "Please push image $MODEL_CONVERTER_IMAGE to image repo if needed\n"
}

# Build image for Model-Measuring
funcBuildImageModel-Measuring() {
    cd $ROOTDIR

    log "Start to build model-measuring image...\n"

    # In model-measuring directory
    cd image/model-measuring
    docker build -t $MODEL_MEASURING_IMAGE ./
    docker push $MODEL_MEASURING_IMAGE
    cd $ROOTDIR

    log "Please push image $MODEL_MEASURING_IMAGE to image repo if needed\n"
}

# Build image for mysql initializing.
funcBuildImageMysqlInit() {
    cd $ROOTDIR

    log "Start to build mysql-init image...\n"

    # In web image directory
    cd image/mysql-ini

    docker build -t $MYSQL_INIT_IMAGE ./
    docker push $MYSQL_INIT_IMAGE
    cd $ROOTDIR

    log "Please push image $MYSQL_INIT_IMAGE to image repo if needed\n"
}
# Build image for elasticsearch initializing.
funcBuildImageElasticsearchInit() {
    cd $ROOTDIR

    log "Start to build elasticsearch-ini image...\n"

    # In web image directory
    cd image/elasticsearch-ini

    docker build -t $ES_INIT_IMAGE ./
    docker push $ES_INIT_IMAGE

    cd $ROOTDIR

    log "Please push image $ES_INIT_IMAGE to image repo if needed\n"
}

# Build image for storage initializing.
funcBuildImageStorageInit() {
    cd $ROOTDIR

    log "Start to build storage-init image...\n"

    # In web image directory
    cd image/storage-ini

    docker build -t $STORAGE_INIT_IMAGE ./
    docker push $STORAGE_INIT_IMAGE

    cd $ROOTDIR

    log "Please push image $STORAGE_INIT_IMAGE to image repo if needed\n"
}

# Build image for nacos initializing.
funcBuildImageNacosInit() {
    cd $ROOTDIR

    log "Start to build nacos-init image...\n"

    # In nacos-init image directory
    cd image/nacos-ini

    docker build -t $NACOS_INIT_IMAGE ./
    docker push $NACOS_INIT_IMAGE
    cd $ROOTDIR

    log "Please push image $NACOS_INIT_IMAGE to image repo if needed\n"
}

# Build image for backend initializing.
funcBuildImageBackendInit() {
    cd $ROOTDIR

    log "Start to build backend-init image...\n"

    # In backend-init image directory
    cd image/backend-ini

    docker build -t $BACKEND_INIT_IMAGE ./
    docker push $BACKEND_INIT_IMAGE
    cd $ROOTDIR

    log "Please push image $BACKEND_INIT_IMAGE to image repo if needed\n"
}
funcBuildImageVisualServer() {
    cd $ROOTDIR

    log "Start to build visual-server image...\n"

    # In backend-init image directory
    cd image/visual-server

    docker build -t $BACKEND_VISUAL_IMAGE ./
    docker push $BACKEND_VISUAL_IMAGE
    cd $ROOTDIR

    log "Please push image $BACKEND_VISUAL_IMAGE to image repo if needed\n"
}

# Build images for all images.
# Or build a certain image.
build-image() {
    image=$1

    if [ ! -d "Dubhe" ]; then
        git clone $GIT_REPO -b $GIT_BRANCH
    fi

    case "$image" in
    all)
        funcBuildImageMysqlInit
        funcBuildImageMinioInit
        funcBuildImageNacosInit
        funcBuildImageElasticsearchInit
        #	    funcBuildImageStorageInit
        funcBuildImageBackendInit
        #            funcBuildImageVisualServer
        #            funcBuildImageBackend
        funcBuildImageWeb
        #            funcBuildImageModel-Converter
        #            funcBuildImageModel-Measuring
        ;;
    mysql-init)
        funcBuildImageMysqlInit
        ;;
    minio-init)
        funcBuildImageMinioInit
        ;;
    nacos-init)
        funcBuildImageNacosInit
        ;;
    backend)
        funcBuildImageBackend
        ;;
    visual-server)
        funcBuildImageVisualServer
        ;;
    backend-init)
        funcBuildImageBackendInit
        ;;
    storage-init)
        funcBuildImageStorageInit
        ;;
    model-converter)
        funcBuildImageModel-Converter
        ;;
    model-measuring)
        funcBuildImageModel-Measuring
        ;;
    web)
        funcBuildImageWeb
        ;;
    esac
}

# Create kubeconfig configmap
createKubeConfigmap() {
    set +e
    cd $ROOTDIR
    kubectl get cm -n dubhe-system kubeconfig > /dev/null 2>&1
    if [ $? -ne 0 ];then
        kubectl create configmap -n dubhe-system kubeconfig --from-file template/kubeconfig.yaml
    fi
    cd $ROOTDIR
    set -e
}

# Install all components.
# TODO: Remove algorithm
install() {
    cd $ROOTDIR
    rm -rf target
    mkdir target

    cat /etc/kubernetes/remote-access.kubeconfig > template/kubeconfig.yaml

    cp -r ./template/yaml target/
    cp -r ./template/algorithm target/
    # Mysql service
    sed -i "s!MYSQL_IMAGE!$MYSQL_IMAGE!g" target/yaml/mysql.yaml
    # Minio Service
    sed -i "s!MINIO_IMAGE!$MINIO_IMAGE!g" target/yaml/minio.yaml
    # Nacos Service
    sed -i "s!NACOS_IMAGE!$NACOS_IMAGE!g" target/yaml/nacos.yaml
    # Redis service
    sed -i "s!REDIS_IMAGE!$REDIS_IMAGE!g" target/yaml/redis.yaml
    sed -i "s!DUBHE_REDIS_PASSWORD!$REDIS_PASSWORD!g" target/yaml/redis.yaml
    # Backend service
    # Currently, Backend service just do initializing work for backend components.
    sed -i "s!MYSQL_INIT_IMAGE!$MYSQL_INIT_IMAGE!g" target/yaml/backend.yaml
    sed -i "s!MINIO_INIT_IMAGE!$MINIO_INIT_IMAGE!g" target/yaml/backend.yaml
    sed -i "s!NACOS_INIT_IMAGE!$NACOS_INIT_IMAGE!g" target/yaml/backend.yaml
    sed -i "s!STORAGE_INIT_IMAGE!$STORAGE_INIT_IMAGE!g" target/yaml/backend.yaml
    sed -i "s!ES_INIT_IMAGE!$ES_INIT_IMAGE!g" target/yaml/backend.yaml
    sed -i "s!BACKEND_IMAGE!$BACKEND_IMAGE!g" target/yaml/backend*.yaml
    sed -i "s!BACKEND_NGINX!$BACKEND_NGINX!g" target/yaml/backend*.yaml
    sed -i "s!BACKEND_INIT_IMAGE!$BACKEND_INIT_IMAGE!g" target/yaml/backend*.yaml
    sed -i "s!BACKEND_VISUAL_IMAGE!$BACKEND_VISUAL_IMAGE!g" target/yaml/backend-visual.yaml
    sed -i "s!DUBHE_REDIS_SERVER!$REDIS_SERVER!g" target/yaml/backend-visual.yaml
    sed -i "s!DUBHE_REDIS_PASSWORD!$REDIS_PASSWORD!g" target/yaml/backend-visual.yaml
    sed -i "s!DUBHE_DUBHE_ENVIRONMENT!$DUBHE_ENVIRONMENT!g" target/yaml/backend*.yaml
    # Algorithim
    sed -i "s!ALGORITHM_IMGPROCESS_IMAGE!$ALGORITHM_IMGPROCESS_IMAGE!g" target/algorithm/algorithm-imgprocess.yaml
    sed -i "s!ALGORITHM_OFRECORD_IMAGE!$ALGORITHM_OFRECORD_IMAGE!g" target/algorithm/algorithm-ofrecord.yaml
    sed -i "s!ALGORITHM_VIDEOSAMPLE_IMAGE!$ALGORITHM_VIDEOSAMPLE_IMAGE!g" target/algorithm/algorithm-videosample.yaml
    sed -i "s!DUBHE_REDIS_SERVER!$REDIS_SERVER!g" target/algorithm/*.yaml
    sed -i "s!DUBHE_REDIS_PASSWORD!$REDIS_PASSWORD!g" target/algorithm/*.yaml
    sed -i "s!BACKEND_INIT_IMAGE!$BACKEND_INIT_IMAGE!g" target/algorithm/*.yaml
    # Web service
    sed -i "s!WEB_IMAGE!$WEB_IMAGE!g" target/yaml/web.yaml
    #MODEL
    ## MODEL_CONVERTER_IMAGE
    sed -i "s!MODEL_CONVERTER_IMAGE!$MODEL_CONVERTER_IMAGE!g" target/yaml/backend-model-converter.yaml
    ## MODEL_MEASURING_IMAGE
    sed -i "s!MODEL_MEASURING_IMAGE!$MODEL_MEASURING_IMAGE!g" target/yaml/backend-model-measure.yaml

    sed -i "s!INFRA_IMAGE!$INFRA_IMAGE!g" target/yaml/elasticsearch.yaml
    sed -i "s!KIBANA_IMAGE!$KIBANA_IMAGE!g" target/yaml/elasticsearch.yaml
    sed -i "s!ELASTICSEARCH_IMAGE!$ELASTICSEARCH_IMAGE!g" target/yaml/elasticsearch.yaml
    sed -i "s!FLUENT_IMAGE!$FLUENT_IMAGE!g" target/yaml/elasticsearch.yaml

    sed -i "s!INFRA_IMAGE!$INFRA_IMAGE!g" target/yaml/monitoring.yaml
    sed -i "s!NODEXPORTER_IMAGE!$NODEXPORTER_IMAGE!g" target/yaml/monitoring.yaml
    sed -i "s!PROMETHEUS_IMAGE!$PROMETHEUS_IMAGE!g" target/yaml/monitoring.yaml
    sed -i "s!GRAFANA_IMAGE!$GRAFANA_IMAGE!g" target/yaml/monitoring.yaml

    sed -i "s!DCM4CHEE_LDAP_IMAGE!$DCM4CHEE_LDAP_IMAGE!g" target/yaml/backend-dcm4chee.yaml
    sed -i "s!DCM4CHEE_LDAP_POSTGRES_IMAGE!$DCM4CHEE_LDAP_POSTGRES_IMAGE!g" target/yaml/backend-dcm4chee.yaml
    sed -i "s!DCM4CHEE_LDAP_ARC_IMAGE!$DCM4CHEE_LDAP_ARC_IMAGE!g" target/yaml/backend-dcm4chee.yaml

    if [ $STORAGE_CLASS = "hostpath" ]; then
        rm target/yaml/pvc.yaml
        # Create storage dir
        mkdir -p $STORAGE_PATH/dubhe-storage
        mkdir -p $STORAGE_PATH/mysql-storage
        mkdir -p $STORAGE_PATH/redis-storage
        mkdir -p $STORAGE_PATH/nacos-storage
        mkdir -p $STORAGE_PATH/dcm4chee-arc
        mkdir -p $STORAGE_PATH/elasticsearch-storage
        mkdir -p $STORAGE_PATH/kibana-storage
        mkdir -p $STORAGE_PATH/prometheus-storage
        mkdir -p $STORAGE_PATH/grafana-storage

        # Replace pvc with hostpath
        sed -i "s!persistentVolumeClaim:!hostPath:!g" target/yaml/*.yaml
        sed -i "s!claimName: dubhe-storage!path: $STORAGE_PATH/dubhe-storage!g" target/yaml/*.yaml
        sed -i "s!claimName: mysql-storage!path: $STORAGE_PATH/mysql-storage!g" target/yaml/*.yaml
        sed -i "s!claimName: nacos-storage!path: $STORAGE_PATH/nacos-storage!g" target/yaml/*.yaml
        sed -i "s!claimName: redis-storage!path: $STORAGE_PATH/redis-storage!g" target/yaml/*.yaml
        sed -i "s!claimName: dcm4chee-arc!path: $STORAGE_PATH/dcm4chee-arc!g" target/yaml/*.yaml
        sed -i "s!claimName: prometheus-storage!path: $STORAGE_PATH/prometheus-storage!g" target/yaml/*.yaml
        sed -i "s!claimName: elasticsearch-storage!path: $STORAGE_PATH/elasticsearch-storage!g" target/yaml/*.yaml
        sed -i "s!claimName: grafana-storage!path: $STORAGE_PATH/grafana-storage!g" target/yaml/*.yaml
        sed -i "s!claimName: kibana-storage!path: $STORAGE_PATH/kibana-storage!g" target/yaml/*.yaml
        sed -i "s!persistentVolumeClaim:!hostPath:!g" target/algorithm/*.yaml
        sed -i "s!claimName: dubhe-storage!path: $STORAGE_PATH/dubhe-storage!g" target/algorithm/*.yaml
    else
        # Volumes
        sed -i "s/STORAGE_CLASS/$STORAGE_CLASS/g" target/yaml/pvc.yaml
        sed -i "s/STORAGE_SIZE/$STORAGE_SIZE/g" target/yaml/pvc.yaml
    fi

    log "Start to deploy Dubhe system.\n"

    # Create namespace and configmap for dubhe.
    kubectl apply -f namespace.yaml
    kubectl apply -f configmap.yaml
    # Create kubeconfig configmap
    createKubeConfigmap
    if [ $STORAGE_CLASS != "hostpath" ]; then
        kubectl apply -f target/yaml/pvc.yaml
    fi
    # Create monitoring and log
    kubectl apply -f ./target/yaml/monitoring.yaml \
        -f ./target/yaml/elasticsearch.yaml
    kubectl -n dubhe-system rollout status deployment/prometheus
    kubectl -n dubhe-system rollout status deployment/elasticsearch

    # Create mysql
    kubectl apply -f ./target/yaml/mysql-console.yaml \
        -f ./target/yaml/mysql.yaml
    kubectl -n dubhe-system rollout status deployment/mysql

    # Create nacos
    kubectl apply -f ./target/yaml/nacos-console.yaml \
        -f ./target/yaml/nacos.yaml
    kubectl -n dubhe-system rollout status deployment/nacos

    # Create minio and redis
    kubectl apply -f ./target/yaml/minio-console.yaml \
        -f ./target/yaml/minio.yaml \
        -f ./target/yaml/redis-console.yaml \
        -f ./target/yaml/redis.yaml

    kubectl -n dubhe-system rollout status deployment/minio
    kubectl -n dubhe-system rollout status deployment/redis

    # Create backend service
    kubectl apply -f ./target/yaml/backend.yaml
    kubectl -n dubhe-system rollout status deployment/backend

    # Create all services defined in template/yaml dir.
    kubectl apply -f target/yaml/
    kubectl apply -f target/algorithm/

    [ -d /nfs ] || ln -s ${STORAGE_PATH}/dubhe-storage/ /nfs

    log "Please wait all pod to be running with:\n"
    log "watch -n 1 'kubectl get po -n dubhe-system'\n"
}

reinstall() {
    cd $ROOTDIR
    module=$1
    # Deploy one algorithm service.
    if [[ $module == algorithm-* ]]; then
        mkdir -p target/algorithm
        cp ./template/algorithm/$module.yaml ./target/algorithm
        sed -i "s!ALGORITHM_IMGPROCESS_IMAGE!$ALGORITHM_IMGPROCESS_IMAGE!g" target/algorithm/algorithm-imgprocess.yaml
        sed -i "s!ALGORITHM_OFRECORD_IMAGE!$ALGORITHM_OFRECORD_IMAGE!g" target/algorithm/algorithm-ofrecord.yaml
        sed -i "s!ALGORITHM_VIDEOSAMPLE_IMAGE!$ALGORITHM_VIDEOSAMPLE_IMAGE!g" target/algorithm/algorithm-videosample.yaml
        sed -i "s!DUBHE_REDIS_SERVER!$REDIS_SERVER!g" target/algorithm/$module.yaml
        sed -i "s!DUBHE_REDIS_PASSWORD!$REDIS_PASSWORD!g" target/algorithm/$module.yaml
        sed -i "s!BACKEND_INIT_IMAGE!$BACKEND_INIT_IMAGE!g" target/algorithm/$module.yaml

        if [ $STORAGE_CLASS = "hostpath" ]; then
            # Replace pvc with hostpath
            sed -i "s!persistentVolumeClaim:!hostPath:!g" target/algorithm/$module.yaml
            sed -i "s!claimName: dubhe-storage!path: $STORAGE_PATH/dubhe-storage!g" target/algorithm/$module.yaml
        fi

        kubectl delete -f target/algorithm/$module.yaml --ignore-not-found=true
        kubectl apply -f target/algorithm/$module.yaml
        return 0
    fi

    # Deploy all algorithm services.
    if [[ $module == algorithm ]]; then
        mkdir -p target/algorithm
        cp ./template/algorithm/*.yaml ./target/algorithm
        sed -i "s!ALGORITHM_IMGPROCESS_IMAGE!$ALGORITHM_IMGPROCESS_IMAGE!g" target/algorithm/algorithm-imgprocess.yaml
        sed -i "s!ALGORITHM_OFRECORD_IMAGE!$ALGORITHM_OFRECORD_IMAGE!g" target/algorithm/algorithm-ofrecord.yaml
        sed -i "s!ALGORITHM_VIDEOSAMPLE_IMAGE!$ALGORITHM_VIDEOSAMPLE_IMAGE!g" target/algorithm/algorithm-videosample.yaml
        sed -i "s!DUBHE_REDIS_SERVER!$REDIS_SERVER!g" target/algorithm/*.yaml
        sed -i "s!DUBHE_REDIS_PASSWORD!$REDIS_PASSWORD!g" target/algorithm/*.yaml
        sed -i "s!BACKEND_INIT_IMAGE!$BACKEND_INIT_IMAGE!g" target/algorithm/*.yaml

        if [ $STORAGE_CLASS = "hostpath" ]; then
            # Replace pvc with hostpath
            sed -i "s!persistentVolumeClaim:!hostPath:!g" target/algorithm/*.yaml
            sed -i "s!claimName: dubhe-storage!path: $STORAGE_PATH/dubhe-storage!g" target/algorithm/*.yaml
        fi

        algorithm_list=("imgprocess" "ofrecord" "videosample")
        for algorithm in ${algorithm_list[*]}; do
            echo "Start to deploy algorithm $algorithm..."
            file="algorithm-${algorithm}.yaml"
            kubectl delete -f target/algorithm/$file --ignore-not-found=true
            kubectl apply -f target/algorithm/$file
        done
        return 0
    fi

    # Deploy aone backend service.
    mkdir -p target/yaml
    log "Start to reinstall module $module\n"
    cp ./template/yaml/$module.yaml ./target/yaml/
    # Just replace all keywords defined in install() func.
    sed -i "s!MYSQL_IMAGE!$MYSQL_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!MINIO_IMAGE!$MINIO_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!NACOS_IMAGE!$NACOS_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!REDIS_IMAGE!$REDIS_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!DUBHE_REDIS_SERVER!$REDIS_SERVER!g" target/yaml/$module.yaml
    sed -i "s!DUBHE_REDIS_PASSWORD!$REDIS_PASSWORD!g" target/yaml/$module.yaml
    sed -i "s!MYSQL_INIT_IMAGE!$MYSQL_INIT_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!MINIO_INIT_IMAGE!$MINIO_INIT_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!NACOS_INIT_IMAGE!$NACOS_INIT_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!STORAGE_INIT_IMAGE!$STORAGE_INIT_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!ES_INIT_IMAGE!$ES_INIT_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!BACKEND_IMAGE!$BACKEND_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!BACKEND_INIT_IMAGE!$BACKEND_INIT_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!BACKEND_VISUAL_IMAGE!$BACKEND_VISUAL_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!WEB_IMAGE!$WEB_IMAGE!g" target/yaml/$module.yaml
    sed -i "s!DUBHE_DUBHE_ENVIRONMENT!$DUBHE_ENVIRONMENT!g" target/yaml/$module.yaml
    ## MODEL_CONVERTER_IMAGE
    sed -i "s!MODEL_CONVERTER_IMAGE!$MODEL_CONVERTER_IMAGE!g" target/yaml/$module.yaml
    ## MODEL_MEASURING_IMAGE
    sed -i "s!MODEL_MEASURING_IMAGE!$MODEL_MEASURING_IMAGE!g" target/yaml/$module.yaml

    if [ $STORAGE_CLASS = "hostpath" ]; then
        # Replace pvc with hostpath
        sed -i "s!persistentVolumeClaim:!hostPath:!g" target/yaml/$module.yaml
        sed -i "s!claimName: dubhe-storage!path: $STORAGE_PATH/dubhe-storage!g" target/yaml/$module.yaml
        sed -i "s!claimName: mysql-storage!path: $STORAGE_PATH/mysql-storage!g" target/yaml/$module.yaml
        sed -i "s!claimName: nacos-storage!path: $STORAGE_PATH/nacos-storage!g" target/yaml/$module.yaml
        sed -i "s!claimName: redis-storage!path: $STORAGE_PATH/redis-storage!g" target/yaml/$module.yaml
        sed -i "s!claimName: dcm4chee-arc!path: $STORAGE_PATH/dcm4chee-arc!g" target/yaml/$module.yaml
    fi

    kubectl delete -f target/yaml/$module.yaml --ignore-not-found=true
    kubectl apply -f target/yaml/$module.yaml

    # Backend components list
    backend_components=("admin" "algorithm" "auth" "data-dcm" "data-task" "data" "gateway" "image" "k8s"
        "measure" "model" "notebook" "optimize" "serving-gateway" "serving" "tadl" "train" "visual"
        "terminal" "dcm4chee" "point-cloud")

    # Reinstall all backend components because nacos config may be changed.
    if [ $module = "backend" ]; then
        cp ./template/yaml/backend-*.yaml ./target/yaml/
        sed -i "s!BACKEND_IMAGE!$BACKEND_IMAGE!g" target/yaml/backend-*.yaml
        sed -i "s!BACKEND_INIT_IMAGE!$BACKEND_INIT_IMAGE!g" target/yaml/backend-*.yaml
        sed -i "s!BACKEND_VISUAL_IMAGE!$BACKEND_VISUAL_IMAGE!g" target/yaml/backend-*.yaml
        sed -i "s!DUBHE_REDIS_SERVER!$REDIS_SERVER!g" target/yaml/backend-*.yaml
        sed -i "s!DUBHE_REDIS_PASSWORD!$REDIS_PASSWORD!g" target/yaml/backend-*.yaml
        if [ $STORAGE_CLASS = "hostpath" ]; then
            # Replace pvc with hostpath
            sed -i "s!persistentVolumeClaim:!hostPath:!g" target/yaml/backend-*.yaml
            sed -i "s!claimName: dubhe-storage!path: $STORAGE_PATH/dubhe-storage!g" target/yaml/backend-*.yaml
            sed -i "s!claimName: dcm4chee-arc!path: $STORAGE_PATH/dcm4chee-arc!g" target/yaml/backend-*.yaml
        fi
        for component in ${backend_components[*]}; do
            file="backend-${component}.yaml"
            echo $file
            kubectl delete -f target/yaml/$file --ignore-not-found=true
            kubectl apply -f target/yaml/$file
            # echo -ne `warn`"后端reinstall，前端请执行reinstall"
            # echo -ne `warn`"./dubhectl reinstall web"
        done
    fi
}

uninstall() {
    kubectl delete configmap -n dubhe-system kubeconfig --ignore-not-found=true
    kubectl delete ns dubhe-system
    log "Namespace dubhe-system is removed\n"
    log "Please remove user namespaces manually\n"
}

usage() {
    log "Usage: \n"
    echo -ne "\t$0 build-image all(mysql-init|minio-init|nacos-init|backend-init|storage-init|backend|web|visual-server|model-converter|model-measuring)\n"
    echo -ne "\t$0 install\n"
    echo -ne "\t$0 reinstall module(mysql|nacos|minio|redis|backend|web)\n"
    echo -ne "\t$0 uninstall\n"
    exit 0
}

err() {
    echo -ne $(error)$* 1>&2
}

log() {
    echo -ne $(info)$* >&1
}

op=$1

shift

case "$op" in
build-image)
    build-image $*
    ;;
install)
    install
    ;;
reinstall)
    reinstall $*
    ;;
uninstall)
    uninstall
    ;;
-h | --help)
    usage
    ;;
*)
    usage
    exit 0
    ;;
esac
